#include <time.h>

#include "../hle.h"

typedef struct {
    u16 year;
    u16 month;
    u16 day;
    u16 hour;
    u16 minutes;
    u16 seconds;
    u32 microseconds;
} PspTime;

void sceRtcGetCurrentClock()
{
    if (mem_isOk(PARAM(0)))
    {
        PspTime pspLocalDate;
        struct tm localDate;
        time_t localTime = time(NULL);
        u32 tz = PARAM(1);
        _log(INF, HLE, "0 = sceRtcGetCurrentClock(%08x)", PARAM(0));
        localtime_r(&localTime, &localDate);
        pspLocalDate.year =    localDate.tm_year + 1900;
        pspLocalDate.month =   localDate.tm_mon;
        pspLocalDate.day =     localDate.tm_mday;
        pspLocalDate.hour =    localDate.tm_hour + (tz / 60);
        pspLocalDate.minutes = localDate.tm_min  + (tz % 60);
        pspLocalDate.seconds = localDate.tm_sec;
        pspLocalDate.microseconds = clock() % CLOCKS_PER_SEC;
        mem_writeStruct(PARAM(0), &pspLocalDate, sizeof(PspTime));
    }
    else {
        _log(ERR, HLE, "-1 = sceRtcGetCurrentClock(%08x)");
        RETURN(-1);
    }
}

void sceRtcGetCurrentClockLocalTime()
{
    if (mem_isOk(PARAM(0)))
    {
        PspTime pspLocalDate;
        struct tm localDate;
        time_t localTime = time(NULL);
        _log(INF, HLE, "0 = sceRtcGetCurrentClockLocalTime(%08x)", PARAM(0));
        localtime_r(&localTime, &localDate);
        pspLocalDate.year =    localDate.tm_year + 1900;
        pspLocalDate.month =   localDate.tm_mon;
        pspLocalDate.day =     localDate.tm_mday;
        pspLocalDate.hour =    localDate.tm_hour;
        pspLocalDate.minutes = localDate.tm_min;
        pspLocalDate.seconds = localDate.tm_sec;
        pspLocalDate.microseconds = clock() % CLOCKS_PER_SEC;
        mem_writeStruct(PARAM(0), &pspLocalDate, sizeof(PspTime));
    }
    else {
        _log(ERR, HLE, "-1 = sceRtcGetCurrentClockLocalTime(%08x)");
        RETURN(-1);
    }
}

void sceRtcGetAccumulativeTime()
{
    clock_t tick;
    u32 lo;
    tick = clock();
    lo = tick & 0xffffffff;
    RETURN(lo);
    RETURN1(0);
    _log(DBG, HLE, "%08x, %08x = sceRtcGetAccumulativeTime()", 0, lo);
}

void sceRtcGetCurrentTick()
{
    /* RETURN(GetTickCount()); */
    RETURN(0);
}

void sceRtcGetTick()
{
    _log(ERR, HLE, "0 = sceRtcGetTick()");
    RETURN(0);
}

void sceRtcGetTickResolution()
{
    _log(ERR, HLE, "100 = sceRtcGetTickResolution()");
    RETURN(100);
}

void sceRtcGetTime64_t()
{
    u32 dateAddr = PARAM(0);
    u32 timeAddr = PARAM(1);
    if (mem_isOk(dateAddr) && mem_isOk(timeAddr))
    {
        PspTime date;
        u64 time;
        struct tm localDate;
        mem_readStruct(dateAddr, &date, sizeof(PspTime));
        localDate.tm_year = date.year - 1900;
        localDate.tm_mon  = date.month;
        localDate.tm_mday = date.day;
        localDate.tm_hour = date.hour;
        localDate.tm_min  = date.minutes;
        localDate.tm_sec  = date.seconds;
        time = mktime(&localDate);
        mem_write64(timeAddr, time);
        _log(INF, HLE, "0 = sceRtcGetTime64_t(%08x, %08x [%016x])", dateAddr, timeAddr, time);
        RETURN(0);
    }
    else {
        _log(ERR, HLE, "sceRtcGetTime64_t(%08x, %08x): bad params!", dateAddr, timeAddr);
        RETURN(-1);
    }

}

